
#include "CmdHandler.h"
#include "Sensor.h"
#include "Mmc.h"
#include "Debug.h"
#include "Command_define.h"
#include "FruInfo.h"
#include "MmcLed.h"
#include "E_Key.h"

#if 1
#define CMD_HANDLE_DUMP() \
	TRACE_LEVEL(TRACE_IPMB|TRACE_INTEG_TEST|TRACE_CMD_HANDLE, ("%s: \n", _FUNC_));	\
	Debug_DumpByteEx(TRACE_IPMB|TRACE_INTEG_TEST|TRACE_CMD_HANDLE, pReqCmd, Reqlen, 32, "\treqData", 0);	\
	Debug_DumpByteEx(TRACE_IPMB|TRACE_INTEG_TEST|TRACE_CMD_HANDLE, pRspCmd, *pRspLen, 32, "\trspData", 0);
#else
#define CMD_HANDLE_DUMP(...)
#endif

int Cmd_GetDeviceID(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
    GetDeviceIDRsp* pRsp = (GetDeviceIDRsp*)pRspCmd;

	memset(pRsp, 0, sizeof(GetDeviceIDRsp));

	
    pRsp->CompCode      	   = COMMAND_COMPLETE;       
    pRsp->Device_ID            = 0x00;       
    pRsp->Device_Revision      = g_Mmc.m_DeviceRev;       
    pRsp->Firmware_Revision_1  = g_Mmc.m_FirmwareMasterRev;       
    pRsp->Firmware_Revision_2  = g_Mmc.m_FirmwareSubRev;    
    pRsp->IPMI_Version         = g_Mmc.m_IpmiRev;
    
    pRsp->EventGenerator 		= 1;  
    pRsp->FRUInventoryDevice 	= 1;  
    pRsp->SDRRepositoryDevice 	= 1;  
    pRsp->SensorDevice 			= 1;  

	*pRspLen = sizeof(GetDeviceIDRsp);

	CMD_HANDLE_DUMP();
	
    return ERR_SUCCESS;                 

}

int Cmd_GetDevSdrInfo(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
    GetDeviceSDRInfoRsp* pRsp = (GetDeviceSDRInfoRsp*)pRspCmd;

    pRsp->m_CompCode   = COMMAND_COMPLETE;
	if(Reqlen >= 1 && (pReqCmd[0] & 0x01))	//Get SDR count
	{
		pRsp->Number = (uint8)Sdr_GetSdrCount(&g_Mmc.m_Sdr, False);
	}
	else	//Get Sensor count
	{
		pRsp->Number = (uint8)Sdr_GetSdrCount(&g_Mmc.m_Sdr, True);
	}	

    pRsp->Flags          = 0x00 | BIT_0;
    pRsp->Indicator_1    = 0x00;
    pRsp->Indicator_2    = 0x00;
    pRsp->Indicator_3    = 0x00;
    pRsp->Indicator_4    = 0x00;

	*pRspLen = sizeof(GetDeviceSDRInfoRsp);
	CMD_HANDLE_DUMP();
    return ERR_SUCCESS;                 
}

int Cmd_GetDevSdr(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
	uint8 maxSize = *pRspLen - 3;
	uint8 len = 0;
	uint16 reservationId = 0;
	uint16 reqRecordId = 0;
	uint16 nextRecord = 0;
	GetDeviceSdrReq* pReq = (GetDeviceSdrReq*)pReqCmd;
	GetDeviceSdrRsq* pRsp = (GetDeviceSdrRsq*)pRspCmd;

	if(Reqlen != sizeof(GetDeviceSdrReq))
	{
		pRsp->m_CompCode = INVALID_DATA_FILED;
		*pRspLen = 1;
		goto End;
	}
	
	reqRecordId = (pReq->m_RecordIdMs<<8) | pReq->m_RecordIdLs;
	reservationId = (pReq->m_ReservationIdMs<<8) | pReq->m_ReservationIdLs;
	
	len = pReq->m_Len;
	if(pReq->m_Len == 0xFF)
	{
		len = maxSize;
	}
	else if(pReq->m_Len > maxSize)
	{
		pRsp->m_CompCode = CANNOT_RETURN_NUMBRE_OF_DATA;
		*pRspLen = 1;
		goto End;
	}

	if(pReq->m_Offset > 0)
	{
		if(reservationId != g_Mmc.m_Sdr.m_ReservationId)
		{
			pRsp->m_CompCode = INVALID_RESERVED_ID;	//record changed
			*pRspLen = 1;
			goto End;
		}
	}

	len = Sdr_GetRecord(&g_Mmc.m_Sdr, reqRecordId, &nextRecord, pReq->m_Offset, pRsp->m_Buff, len);

	pRsp->m_CompCode = 0;
	pRsp->m_NextIdLs = (uint8)nextRecord;
	pRsp->m_NextIdMs = (uint8)(nextRecord >> 8);
	
	*pRspLen = len + 3;
End:	
    CMD_HANDLE_DUMP();
    return ERR_SUCCESS;                 
}

int Cmd_ReserveDevSdrRepo(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
	pRspCmd[0] = COMMAND_COMPLETE;
	pRspCmd[1] = (uint8)g_Mmc.m_Sdr.m_ReservationId;	//Reservation ID LS Byte
	pRspCmd[2] = (uint8)(g_Mmc.m_Sdr.m_ReservationId >> 8);	

	*pRspLen = 3;
	
    CMD_HANDLE_DUMP();
    return ERR_SUCCESS;                 
}

int Cmd_GetSensorReading(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
    GetSensorReadingRsp* pRsp = (GetSensorReadingRsp*)pRspCmd;
	Sensor* pSensor = Null;

	if(Reqlen != 1)
	{
		pRsp->m_CompCode = INVALID_DATA_FILED;
		*pRspLen = 1;
		goto End;
	}

	pSensor = Mmc_GetSensor(pReqCmd[0]);
	if(pSensor)
	{
		pRsp->m_CompCode = COMMAND_COMPLETE;
		pRsp->m_SensorReading  = pSensor->m_RawValue;
		pRsp->m_Status  = pSensor->m_isEventMsgEnable << 7;
		pRsp->m_Status  |= pSensor->m_isScanEnable << 6;
		pRsp->m_Status  |= pSensor->m_isReadingUnavailable << 5;
		pRsp->m_ComparisonStatus1  = (uint8)pSensor->m_ReadingEvent;
		pRsp->m_ComparisonStatus2  = (uint8)(pSensor->m_ReadingEvent>>8);
	}
	else
	{
		pRsp->m_CompCode = REQUESTED_NOT_PRESENT;
		*pRspLen = 1;
		goto End;
	}

	*pRspLen = sizeof(GetSensorReadingRsp);
End:	
    CMD_HANDLE_DUMP();
    return ERR_SUCCESS;                 
}

int Cmd_SetEventReceiver(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
	if(Reqlen == 2)
	{
		pRspCmd[0] = COMMAND_COMPLETE;
		Mmc_SetEventReceiver(pReqCmd[0], pReqCmd[1] & 0x03);
		Mmc_SensorReset();
	}
	else
	{
		pRspCmd[0] = INVALID_DATA_FILED;
	}

	*pRspLen = 1;
    CMD_HANDLE_DUMP();
    return ERR_SUCCESS;                 
}

int Cmd_SetEventEnable(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
	Sensor* pSensor = Mmc_GetSensor(pReqCmd[0]);
	Operate* pOperate = (Operate*)&pReqCmd[1];
	uint8* pAssertMask = Null;
	uint8* pDeassertMask = Null;

	if(Reqlen < 2)
	{
		pRspCmd[0] = INVALID_DATA_LENGTH;
		goto End;
	}

	if(Null == pSensor)
	{
		pRspCmd[0] = INVALID_DATA_FILED;
		goto End;
	}
	
	if(pSensor->m_pRecodHeader->m_Type != SDR_COMPACT_SENSOR)
	{
		 pAssertMask = (uint8*)&(((CompactSensorRecord*)pSensor->m_pRecodHeader)->m_LowerThresholdMask);
		 pDeassertMask = (uint8*)&(((CompactSensorRecord*)pSensor->m_pRecodHeader)->m_UpperThresholdMask);
	}
	else if(pSensor->m_pRecodHeader->m_Type != SDR_FULL_SENSOR)
	{
		 pAssertMask = (uint8*)&(((FullSensorRecord*)pSensor->m_pRecodHeader)->m_LowerThresholdMask);
		 pDeassertMask = (uint8*)&(((FullSensorRecord*)pSensor->m_pRecodHeader)->m_UpperThresholdMask);
	}
	else
	{
		pRspCmd[0] = INVALID_DATA_FILED;
		goto End;
	}

	pRspCmd[0] = COMMAND_COMPLETE;
	if(1 == pOperate->m_Feature)	//enable selected event messages
	{
		if(Reqlen >= 3)
		{
			pAssertMask[0] |= pReqCmd[2];
		}
		if(Reqlen >= 4)
		{
			pAssertMask[1] |= pReqCmd[3];
		}
		
		if(Reqlen >= 5)
		{
			pDeassertMask[0] |= pReqCmd[4];
		}
		if(Reqlen >= 6)
		{
			pDeassertMask[1] |= pReqCmd[5];
		}
	}
	else if(2 == pOperate->m_Feature)	//disable selected event messages
	{
		if(Reqlen >= 3)
		{
			pAssertMask[0] &= ~pReqCmd[2];
		}
		if(Reqlen >= 4)
		{
			pAssertMask[1] &= ~pReqCmd[3];
		}
		
		if(Reqlen >= 5)
		{
			pDeassertMask[0] &= ~pReqCmd[4];
		}
		if(Reqlen >= 6)
		{
			pDeassertMask[1] &= ~pReqCmd[5];
		}
	}

End:	
	*pRspLen = 1;
	
    CMD_HANDLE_DUMP();
    return ERR_SUCCESS;                 
	
}

int Cmd_GetEventRev(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
    GetEventReceiverRsp* pRsp = (GetEventReceiverRsp*)pRspCmd;

    pRsp->m_CompCode = COMMAND_COMPLETE;
    pRsp->Rec_Slave_Add   = g_Mmc.m_ReceiverAddress;
    pRsp->Rec_LUN         = g_Mmc.m_ReceiverLun;

	*pRspLen = sizeof(GetEventReceiverRsp);
    CMD_HANDLE_DUMP();
    return ERR_SUCCESS;                 
}

int Cmd_GetFruInventory(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
    GetFruInfoRsp* pRsp = (GetFruInfoRsp*)pRspCmd;

    pRsp->m_CompCode       = COMMAND_COMPLETE;
    pRsp->m_FruAreaSizeLs  = (uint8)g_Mmc.m_FruInfo.m_UsedBufLen;
    pRsp->m_FruAreaSizeMs  = (uint8)(g_Mmc.m_FruInfo.m_UsedBufLen >> 8);
    pRsp->m_AccessMode     = 0;	//0b = Device is accessed by bytes, 1b = Device is accessed by words 

	*pRspLen = sizeof(GetFruInfoRsp);
    CMD_HANDLE_DUMP();
    return ERR_SUCCESS;                 
}

int Cmd_ReadFruData(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
	int nRet = 0;
	uint16 nLen = 0;
    int offset = 0;
    ReadFruDataReq *pReq = (ReadFruDataReq*)pReqCmd;
	ReadFruDataRsp* pRspData = (ReadFruDataRsp*)pRspCmd;

	if(Reqlen != 4)
	{
		pRspData->m_CompCode = INVALID_DATA_FILED;
		nLen = 1;
		goto End;
	}

    offset = (((pReq->m_OffsetMs)<<8) 
		| (pReq->m_OffsetLs));

	nLen = pReq->m_Count;
	if(pReq->m_Count > *pRspLen - 2)
	{
		nLen = 1;
		pRspData->m_CompCode = INVALID_DATA_LENGTH;
		goto End;
	}
	
	nRet = FruInfo_ReadOffset(&g_Mmc.m_FruInfo, offset, pRspData->m_Data, nLen);
	
	if(nRet)
	{
		pRspData->m_CompCode = COMMAND_COMPLETE;
		pRspData->m_Count = pReq->m_Count;
		nLen = pReq->m_Count + 2;
	}
	else
	{
		nLen = 1;
		pRspData->m_CompCode = UNSPECIFIED_ERROR;
		goto End;
	}
	
End:
	TRACE_LEVEL(TRACE_CMD_HANDLE, ("%s() len=%d, nRet=%d\n", _FUNC_, nLen, nRet));
	
	*pRspLen = (uint8)nLen;
    CMD_HANDLE_DUMP();
    return ERR_SUCCESS;                 
}


int Cmd_WriteFruData(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
	int nRet = ERR_UNKNOWN;
	uint16 nLen = 0;
    int offset = 0;
    WriteFruDataReq *pReq = (WriteFruDataReq*)pReqCmd;
	WriteFruDataRsp* pRspData = (WriteFruDataRsp*)pRspCmd;

	if(Reqlen <= 3)
	{
		nLen = 1;
		pRspData->m_CompCode = INVALID_DATA_LENGTH;
		goto End;
	}
	
	nLen = Reqlen - 3;
    offset = (((pReq->m_OffsetMs)<<8) 
		| (pReq->m_OffsetLs));

	if(nLen > *pRspLen - 3)
	{
		nLen = 1;
		pRspData->m_CompCode = INVALID_DATA_LENGTH;
		goto End;
	}

	nRet = FruInfo_WriteOffset(&g_Mmc.m_FruInfo, offset, pReq->m_Data, nLen);

	if(nRet)
	{
		pRspData->m_CompCode = COMMAND_COMPLETE;
		pRspData->m_Count = (uint8)nLen;
		nLen = 2;
	}
	else
	{
		nLen = 1;
		pRspData->m_CompCode = UNSPECIFIED_ERROR;
		goto End;
	}
	
End:

	TRACE_LEVEL(TRACE_CMD_HANDLE, ("%s() len=%d, nRet=%d\n", _FUNC_, nLen, nRet));
	*pRspLen = (uint8)nLen;
    CMD_HANDLE_DUMP();
    return ERR_SUCCESS;                 
}

int Cmd_GetPicmgPorperties(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
	uint8 num 	= 0;
	pRspCmd[num++] = COMMAND_COMPLETE;
	pRspCmd[num++] = PICMG_IDENTIFIER;
	pRspCmd[num++] = 0x14;
	pRspCmd[num++] = 0x00;
	pRspCmd[num++] = 0x00;

	* pRspLen = num;
	CMD_HANDLE_DUMP();
    return ERR_SUCCESS;
}

int Cmd_FruControlCapabilities(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
	pRspCmd[0] = COMMAND_COMPLETE;
	pRspCmd[1] = PICMG_IDENTIFIER;
	pRspCmd[2] = AS_UINT8(g_Mmc.m_FruCtrlCapMask);
	
	* pRspLen = 3;
	CMD_HANDLE_DUMP();
    return ERR_SUCCESS;
}

int Cmd_FruControl(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
	static const char* str[] = 
	{
		"FRU_CTRL_COLD_RESET"
		,"FRU_CTRL_WARM_RESET"
		,"FRU_CTRL_GRACEFUL_REBOOT"
		,"FRU_CTRL_DIAGNOSTIC_INTERRUPT"
		,"UN_KNOWN"
	};
	ReqData payloadReq={0};
    unsigned char control_ste = 0;	
    FruControlRsp* pRsp = (FruControlRsp*)pRspCmd;
    FruControlReq *pReq = (FruControlReq *)pReqCmd;

    control_ste = pReq->FRU_Control;
   
    pRsp->m_CompCode   = COMMAND_COMPLETE;
    pRsp->PICMG_ID          = 0;
	*pRspLen = sizeof(FruControlRsp);

	if(control_ste < FRU_CTRL_DIAGNOSTIC_INTERRUPT)
	{
		TRACE_LEVEL(TRACE_CMD_HANDLE | TRACE_INTEG_TEST,("%s(%s)\n", _FUNC_, str[control_ste]));
	}
	else
	{
		TRACE_LEVEL(TRACE_CMD_HANDLE | TRACE_INTEG_TEST,("%s(UN_KNOWN)\n", _FUNC_));
	}
	
	payloadReq.m_Cmd = FRU_CONTROL;
	payloadReq.m_NetFn = NETFUN_PICMG_REQ;
	payloadReq.m_Lun = CARRIET_LUN;
	payloadReq.m_reSendCounter = 5;
	payloadReq.m_len = Reqlen;
	memcpy(payloadReq.m_buff, pReqCmd, Reqlen);
	
    switch(control_ste)
    {
		case FRU_CTRL_COLD_RESET:
            break;
        case FRU_CTRL_WARM_RESET:
			if(!g_Mmc.m_FruCtrlCapMask.m_WarmReset || !Crb_SendReq((Crb*)&g_Mmc.m_UartReqCrb, &payloadReq))
			{
				*pRspLen = 1;
	   			pRsp->m_CompCode = CANNOT_EXECUTE_COMMAND;
			}
			break;
		case FRU_CTRL_GRACEFUL_REBOOT:
 			if(!g_Mmc.m_FruCtrlCapMask.m_GracefulReboot || !Crb_SendReq((Crb*)&g_Mmc.m_UartReqCrb, &payloadReq))
			{
				*pRspLen = 1;
	   			pRsp->m_CompCode = CANNOT_EXECUTE_COMMAND;
			}
			break;
       case FRU_CTRL_QUIESCE:
			if(!Crb_SendReq((Crb*)&g_Mmc.m_UartReqCrb, &payloadReq))
			{
				*pRspLen = 1;
	   			pRsp->m_CompCode = CANNOT_EXECUTE_COMMAND;
			}
            break;
       case FRU_CTRL_DIAGNOSTIC_INTERRUPT:
			if(!g_Mmc.m_FruCtrlCapMask.m_DiagnosticInterrupt)
			{
				*pRspLen = 1;
	   			pRsp->m_CompCode = CANNOT_EXECUTE_COMMAND;
			}
            break;
        default:
			*pRspLen = 1;
   			pRsp->m_CompCode = INVALID_DATA_FILED;
            break;
    }
    

    CMD_HANDLE_DUMP();
    return ERR_SUCCESS;                 
}

int Cmd_GetFruLedProper(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
	GetFruLedPropertiesRsp *pRsp = (GetFruLedPropertiesRsp*)pRspCmd;

	pRsp->m_CompCode 				= COMMAND_COMPLETE;
	pRsp->PICMG_ID					= PICMG_IDENTIFIER;
	pRsp->General_Status_LEDs		= BIT_0|BIT_1;
	pRsp->Application_Status_LEDs	= 1;

	*pRspLen = sizeof(GetFruLedPropertiesRsp);
    CMD_HANDLE_DUMP();
    return ERR_SUCCESS;                 
}

int Cmd_SetFruLedSte(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
	//int len = 1;
    SET_FRU_LED_STATE_REQ *pReq = (SET_FRU_LED_STATE_REQ *)pReqCmd;
    SET_FRU_LED_STATE_RSP* pRsp = (SET_FRU_LED_STATE_RSP*)pRspCmd;
	Led* pLed = Null;

	if(Reqlen != sizeof(SET_FRU_LED_STATE_REQ))
	{
		pRsp->m_CompCode = INVALID_DATA_FILED;
	 	*pRspLen = 1;
		goto End;
	}

	if(0xFF == pReq->LED_ID)
	{
		pLed = Mmc_GetLed(BLUE_LED);
		if(!Led_SetState(pLed, pReq->Color, pReq->LED_Function, pReq->On_Duraton)) goto End;
		
		pLed = Mmc_GetLed(LED1_LED);
		if(!Led_SetState(pLed, pReq->Color, pReq->LED_Function, pReq->On_Duraton)) goto End;
	}
	else
	{
		pLed = Mmc_GetLed(pReq->LED_ID);
		if(Null == pLed)
		{
			pRsp->m_CompCode = REQUESTED_NOT_PRESENT;
			goto End;
		}
		if(!Led_SetState(pLed, pReq->Color, pReq->LED_Function, pReq->On_Duraton))
		{
			pRsp->m_CompCode = INVALID_DATA_FILED;
			goto End;
		}
	}
	
    pRsp->m_CompCode = COMMAND_COMPLETE;
    pRsp->PICMG_ID   = 0;
 	*pRspLen = sizeof(SET_FRU_LED_STATE_RSP);
    CMD_HANDLE_DUMP();
    return ERR_SUCCESS;                 
	
End:
 	*pRspLen = 1;
    CMD_HANDLE_DUMP();
    return ERR_SUCCESS;                 
}

int Cmd_GetFruLedSte(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
    GET_FRU_LED_STATE_REQ *pReq =(GET_FRU_LED_STATE_REQ *)pReqCmd;
	uint8 num = 0;
	Led* pLed = Mmc_GetLed(pReq->LED_ID);
	
	if(Reqlen != sizeof(GET_FRU_LED_STATE_REQ))
	{
		pRspCmd[0] = INVALID_DATA_FILED;
	 	num = 1;
		goto End;
	}

	if(pLed)
	{
		pRspCmd[num++]		= COMMAND_COMPLETE;		
		pRspCmd[num++]		= PICMG_IDENTIFIER;	
		num += Led_GetState(pLed, &pRspCmd[num], 8);
	}
	else
	{
		num = 1;
		pRspCmd[0] = REQUESTED_NOT_PRESENT;
		goto End;
	}
	
End:
 	*pRspLen = num;
    CMD_HANDLE_DUMP();
    return ERR_SUCCESS;                 
}

int Cmd_GetLEDColorCap(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
	int len = 1;
	GET_LED_COLOR_CAPABILITIES_REQ *pReq = (GET_LED_COLOR_CAPABILITIES_REQ*)pReqCmd;
	GET_LED_COLOR_CAPABILITIES_RSP *pRsp = (GET_LED_COLOR_CAPABILITIES_RSP*)pRspCmd;
	Led* pLed = Mmc_GetLed(pReq->LED_ID);

	if(Reqlen != sizeof(GET_LED_COLOR_CAPABILITIES_REQ))
	{
		pRsp->m_CompCode = INVALID_DATA_FILED;
		* pRspLen = 1;
		goto End;
	}
	
	if(pLed)
	{
		pRsp->m_CompCode 					= COMMAND_COMPLETE;
		pRsp->PICMG_ID						= PICMG_IDENTIFIER;
		pRsp->LED_Color_Capabilities		= *(uint8*)&pLed->m_ColorCapabilities;
		pRsp->Default_color_Local_state 	= pLed->m_DefaultColorInLocalCtrlState;
		pRsp->Default_color_Override_state 	= pLed->m_DefaultColorInOverrideCtrlState;
		len = sizeof(GET_LED_COLOR_CAPABILITIES_RSP);
	}
	else
	{
		len = 1;
		pRsp->m_CompCode = REQUESTED_NOT_PRESENT;
	}


	* pRspLen = len;
End:
	CMD_HANDLE_DUMP();
    return ERR_SUCCESS;
}


int Cmd_SetAmcPortSte(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
	int len = 1;
    uint8 iRst ;
     
	SET_PORT_STATE_REQ *pReq = (SET_PORT_STATE_REQ*)pReqCmd;
	SET_PORT_STATE_RSP *pRsp = (SET_PORT_STATE_RSP*)pRspCmd;
    
	if(Reqlen != sizeof(SET_PORT_STATE_REQ))
	{
		pRsp->m_CompCode = INVALID_DATA_FILED;
		* pRspLen = 1;
		goto End;
	}

    iRst = E_keying_SetPortState(&g_Mmc.m_E_Keying,pReq->m_SetState,pReq->m_LinkInfo);
    if(!iRst)
    {
        pRsp->m_CompCode = COMMAND_COMPLETE;
        pRsp->PICMG_ID   = PICMG_IDENTIFIER;
        len = sizeof(SET_PORT_STATE_RSP);
    }
	else
	{
		len = 1;
		pRsp->m_CompCode = REQUESTED_NOT_PRESENT;
	}

    
	* pRspLen = len;
    
End:
	CMD_HANDLE_DUMP();
    return ERR_SUCCESS;
}
int Cmd_GetAmcPortSte(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
    int len = 1;
    
    GET_PORT_STATE_REQ *pReq = (GET_PORT_STATE_REQ*)pReqCmd;
    GET_PORT_STATE_RSP *pRsp = (GET_PORT_STATE_RSP*)pRspCmd;
    
    if(Reqlen != sizeof(GET_PORT_STATE_REQ))
    {
        pRsp->m_CompCode = INVALID_DATA_FILED;
        * pRspLen = 1;
        goto End;
    }

    pRsp->m_GetState1 = E_keying_GetPortState(&g_Mmc.m_E_Keying,pReq->mChannelId,pRsp->m_LinkInfo1);
    pRsp->m_CompCode = COMMAND_COMPLETE;
    pRsp->PICMG_ID   = PICMG_IDENTIFIER;
    len = sizeof(GET_PORT_STATE_RSP);
        
    * pRspLen = len;
    
End:
    CMD_HANDLE_DUMP();
    return ERR_SUCCESS;
}

int Cmd_GetLocatorRecordId(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
	if(Reqlen < 2 || Reqlen > 4)
	{
		pRspCmd[0] = INVALID_DATA_FILED;
		* pRspLen = 1;
		goto End;
	}
 	
	pRspCmd[0] = COMMAND_COMPLETE;
	pRspCmd[1] = PICMG_IDENTIFIER;
	pRspCmd[2] = 0;
	pRspCmd[3] = 0;

	*pRspLen = 4;
End:
    CMD_HANDLE_DUMP();
    return ERR_SUCCESS;
}

int Cmd_GetAddressInfo(const uint8* pReqCmd, uint8 Reqlen, uint8* pRspCmd, uint8* pRspLen)
{
 	
	pRspCmd[0] = COMMAND_COMPLETE;
	pRspCmd[1] = PICMG_IDENTIFIER;
	pRspCmd[2] = g_Owerner_Sit_Num;
	pRspCmd[3] = g_Owerner_IPMB_Addr;
	pRspCmd[4] = 0xFF;
	pRspCmd[5] = g_Owerner_Sit_Num;
	pRspCmd[6] = 0;
	pRspCmd[7] = g_Owerner_SIT_TYPE;
	pRspCmd[8] = 0;

	*pRspLen = 9;
    CMD_HANDLE_DUMP();
    return ERR_SUCCESS;
}


const IpmiCmdHandler	g_CmdEventLunCmdHandlers[] = 
{
	  {NETFUN_APPLICA_REQ ,GET_DEVICE_ID		,(CmdHandlerFun)Cmd_GetDeviceID}    
	 ,{NETFUN_SSEVENT_REQ ,GET_DEVICE_SDR_INFO	,(CmdHandlerFun)Cmd_GetDevSdrInfo}
	 ,{NETFUN_SSEVENT_REQ ,GET_DEVICE_SDR	 	,(CmdHandlerFun)Cmd_GetDevSdr}
	 ,{NETFUN_SSEVENT_REQ ,RESERVE_DEVICE_SDR_REPOSITORY,(CmdHandlerFun)Cmd_ReserveDevSdrRepo}
	 ,{NETFUN_SSEVENT_REQ ,GET_SENSOR_READING 	,(CmdHandlerFun)Cmd_GetSensorReading}
	 ,{NETFUN_SSEVENT_REQ ,SET_EVENT_RECEIVER 	,(CmdHandlerFun)Cmd_SetEventReceiver}
	 ,{NETFUN_SSEVENT_REQ ,GET_EVENT_RECEIVER 	,(CmdHandlerFun)Cmd_GetEventRev}

	 ,{NETFUN_STORAGE_REQ ,GET_FRU_INVENTORY_INFO,(CmdHandlerFun)Cmd_GetFruInventory}
	 ,{NETFUN_STORAGE_REQ ,READ_FRU_DATA		,(CmdHandlerFun)Cmd_ReadFruData}
	 ,{NETFUN_STORAGE_REQ ,WRITE_FRU_DATA		,(CmdHandlerFun)Cmd_WriteFruData}
     
	 ,{NETFUN_PICMG_REQ ,GET_PICMG_PROPERTY 	,(CmdHandlerFun)Cmd_GetPicmgPorperties}
	 ,{NETFUN_PICMG_REQ ,FRU_CONTROL_CAPABILTY	,(CmdHandlerFun)Cmd_FruControlCapabilities}
	 ,{NETFUN_PICMG_REQ ,FRU_CONTROL			,(CmdHandlerFun)Cmd_FruControl}
	 ,{NETFUN_PICMG_REQ ,GET_FRU_LED_PROPERTY	,(CmdHandlerFun)Cmd_GetFruLedProper}
	 ,{NETFUN_PICMG_REQ ,GET_LED_COLOR_CAPABT	,(CmdHandlerFun)Cmd_GetLEDColorCap}
	 ,{NETFUN_PICMG_REQ ,SET_FRU_LED_STATE		,(CmdHandlerFun)Cmd_SetFruLedSte}
	 ,{NETFUN_PICMG_REQ ,GET_FRU_LED_STATE		,(CmdHandlerFun)Cmd_GetFruLedSte}
 	 ,{NETFUN_PICMG_REQ ,GET_ADDRESS_INFO		,(CmdHandlerFun)Cmd_GetAddressInfo}
 	 ,{NETFUN_PICMG_REQ ,GET_LOCATOR_RECORD_ID	,(CmdHandlerFun)Cmd_GetLocatorRecordId}
	 ,{NETFUN_PICMG_REQ ,SET_AMC_PORT_STATE		,(CmdHandlerFun)Cmd_SetAmcPortSte}
	 ,{NETFUN_PICMG_REQ ,GET_AMC_PORT_STATE		,(CmdHandlerFun)Cmd_GetAmcPortSte}	
};

const uint8 g_CmdCounts = sizeof(g_CmdEventLunCmdHandlers)/sizeof(IpmiCmdHandler);


// ERR_SUCCESS: IPMI commands is handled by the IPMI firmware
// ERR_FAILED: IPMI commands not supported by the IPMI firmware
int Cmd_Disptch(IpmiCmd* pReq, IpmiCmd* pRsp)
{
	int i = 0;
	int iResult = ERR_FAILED;
	uint8 nRspLen = pReq->m_MaxCmdDataLen;
    const IpmiCmdHandler* pHandler = g_CmdEventLunCmdHandlers;

	for(i = 0; i < g_CmdCounts; i++, pHandler++)
	{
		if(pReq->m_Header.m_Cmd == pHandler->cmd && pReq->m_Header.m_NetFn == pHandler->netFnLun)
		{
			iResult = pHandler->cmdHandler(pReq->m_pCmdData
				, pReq->GetDataLen(pReq)
				, pRsp->m_pCmdData
				, &nRspLen);

			if(iResult == ERR_SUCCESS)
			{
				pRsp->SetDataLen(pRsp, nRspLen);
			}

			return iResult;
		}
	}

	//IPMI commands not supported by the IPMI firmware
	return ERR_FAILED;
}

int Cmd_DisptchPayload(IpmiCmd* pReq, IpmiCmd* pRsp)
{
	if(pReq->m_Header.m_Lun == 0x02)
	{
		pRsp->m_pCmdData[0] = 0xCC;
		pRsp->SetDataLen(pRsp, 1);
		return ERR_SUCCESS;
	}

	return Cmd_Disptch(pReq, pRsp);
}


